import { useRefValue } from '@gnlab/utils/env-react'

interface DragInfo {
  startPos: number | null // 开始拖拽时的 X/Y 坐标；为 null 代表未开始
  startSize: number
}

function calculateNumber(num?: number | (() => number)) {
  if (typeof num === 'number' && isFinite(num)) return num
  if (typeof num === 'function') return num()
  return null
}

export function useResize({
  side = 'y',
  reverse = false,
  current: currentSize,
  onResize,
  min,
  max,
}: {
  side?: 'x' | 'y' // 横向还是竖向拖动
  reverse?: boolean // reverse=false 向右、向下变大；reverse=true 向左、向上变大
  current: number
  onResize: (size: number) => void
  min?: number | (() => number)
  max?: number | (() => number)
}) {
  const infoRef = useRef<DragInfo>({ startPos: null, startSize: 0 })
  const minRef = useRefValue(min)
  const maxRef = useRefValue(max)

  const onMouseMove = useCallback(
    (event: MouseEvent) => {
      event.stopPropagation()
      event.preventDefault()

      const { startPos, startSize } = infoRef.current
      if (startPos === null) return

      const currentPos = side === 'x' ? event.screenX : event.screenY
      const nextSize = startSize - (reverse ? currentPos - startPos : startPos - currentPos)

      const min = calculateNumber(minRef.current) ?? nextSize
      const max = calculateNumber(maxRef.current) ?? nextSize
      const scaled = Math.max(Math.min(nextSize, max), min)
      const scaledLog = scaled === nextSize ? '' : `, scaled: ${scaled}`

      console.log(
        `resize, ${side}: ${currentPos}, size: ${nextSize},${scaledLog} reverse: ${reverse}`,
      )
      onResize(scaled)
    },
    [onResize, side, reverse],
  )

  const onMouseUp = useCallback(() => {
    console.log('finish resize')
    infoRef.current = { startPos: null, startSize: 0 }
    window.removeEventListener('mouseup', onMouseUp)
    window.removeEventListener('mousemove', onMouseMove)
  }, [onMouseMove])

  const onMouseDown = useCallback(
    (event: React.MouseEvent<HTMLDivElement>) => {
      const pos = side === 'x' ? event.screenX : event.screenY
      console.log(`start resize, ${side}: ${pos}, size: ${currentSize}, reverse: ${reverse}`)
      infoRef.current = { startPos: pos, startSize: currentSize }
      window.addEventListener('mouseup', onMouseUp)
      window.addEventListener('mousemove', onMouseMove)
    },
    [side, reverse, currentSize, onMouseMove, onMouseUp],
  )

  return {
    onMouseDown,
    onMouseUp,
  }
}
